using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate.Criterion;
using NHibernate.Linq;
using Ornament.Domain;
using Ornament.MemberShip.Permissions;
using Ornament.NHibernates;

namespace Ornament.MemberShip.Dao.NHibernateImple
{
    /// <summary>
    /// 
    /// </summary>
    public class PermissionDao : DaoBase<Guid, Permission>, IPermissionDao
    {
        public PermissionDao()
        {
        }

        public PermissionDao(bool useGlobalSession)
            : base(useGlobalSession)
        {
        }

        protected override Order[] DefaultOrder
        {
            get { return new[] { Order.Asc(Projections.Property<Permission>(s => s.Name)) }; }
        }

        #region IPermissionDao Members

        public IList<Permission> GetUserPermissions(string loginId, Type resourceType)
        {
            throw new NotImplementedException();
        }



        public IList<Permission> GetPermissionByLoginId(string loginid)
        {
            DetachedCriteria user =
                DetachedCriteria.For(typeof(User)).Add(Restrictions.Eq("LoginId", loginid))
                    .SetProjection(null)
                    .CreateCriteria("Roles")
                    .CreateCriteria("Permissions", "permission")
                    .SetProjection(Projections.Distinct(Projections.Property("permission.Id")));

            DetachedCriteria permission =
                DetachedCriteria.For(typeof(Permission)).Add(Property.ForName("Id").In(user));
            return permission.GetExecutableCriteria(CurrentSession).List<Permission>();
        }

        public IList<Permission> GetUserPermissions(string loginid, object resourceObject)
        {
            DetachedCriteria user =
                DetachedCriteria.For(typeof(User)).Add(Restrictions.Eq("LoginId", loginid))
                    .CreateCriteria("Roles")
                    .CreateCriteria("Permissions", "permission")
                    .SetProjection(Projections.Distinct(Projections.Property("permission.Id")));

            var permissionInsType = Permission.CreatePermission(resourceObject).GetType();
            DetachedCriteria permission = DetachedCriteria.For(permissionInsType)
                .Add(Restrictions.Eq("Resource", resourceObject));

            permission.Add(Subqueries.PropertyIn("Id", user));
            return permission.GetExecutableCriteria(CurrentSession).List<Permission>();
        }


        public Permission GetPermission(string permissionName)
        {
            DetachedCriteria a = DetachedCriteria.For<Permission>().Add(Restrictions.Eq("Name", permissionName));
            return a.GetExecutableCriteria(CurrentSession).UniqueResult<Permission>();
        }

        public IQueryable<Permission> Permissions
        {
            get { return SessionManager.Instance.CurrentSession.Query<Permission>(); }
        }

        #endregion
    }
}